# import os
# import re
# import subprocess

# def listen_tap_events():
#     """监听设备的点击事件并打印坐标"""
#     # 启动 ADB 命令监听点击事件
#     process = subprocess.Popen(
#         ["adb", "shell", "getevent"],  # 监听设备事件
#         stdout=subprocess.PIPE,
#         stderr=subprocess.PIPE,
#         universal_newlines=True,
#     )

#     # 正则表达式匹配点击事件
#     event_pattern = re.compile(r"event(\d+):\s+(\w+)\s+(\w+)\s+(\w+)")

#     try:
#         while True:
#             output = process.stdout.readline()
#             if output == "" and process.poll() is not None:
#                 break
#             if output:
#                 # 解析事件日志
#                 match = event_pattern.search(output)
#                 if match:
#                     event_type = match.group(2)
#                     event_code = match.group(3)
#                     event_value = match.group(4)

#                     # 判断是否为点击事件
#                     if event_type == "0003" and event_code == "0035":  # ABS_MT_POSITION_X
#                         x = int(event_value, 16)  # 16 进制转 10 进制
#                     elif event_type == "0003" and event_code == "0036":  # ABS_MT_POSITION_Y
#                         y = int(event_value, 16)  # 16 进制转 10 进制
#                         print(f"点击坐标：({x}, {y})")  # 打印坐标
#     except KeyboardInterrupt:
#         print("监听已停止")
#     finally:
#         process.terminate()

# # ------------------- 主逻辑 -------------------
# if __name__ == "__main__":
#     print("开始监听点击事件，按 Ctrl+C 停止...")
#     listen_tap_events()

import cv2
import numpy as np
import pyautogui
import time

class SmartGrillMonitor:
    def __init__(self, regions_config, click_position=(0,0), 
                 check_interval=0.8, display_scale=1.0, cooldown=5.0):
        """
        智能烤架监控系统
        :param regions_config: 区域配置列表
        :param click_position: 相对主区域的点击坐标
        :param check_interval: 检测间隔（秒）
        :param display_scale: 显示缩放比例
        :param cooldown: 点击冷却时间（秒）
        """
        # 主监控区域定义（屏幕绝对坐标）
        self.main_roi = (475, 330, 950, 430)  # x, y, width, height
        self.display_scale = display_scale
        self.cooldown = cooldown
        
        # 初始化监控区域
        self.monitors = []
        for cfg in regions_config:
            # 转换为绝对坐标
            abs_tl = (
                self.main_roi[0] + cfg['top_left'][0],
                self.main_roi[1] + cfg['top_left'][1]
            )
            abs_br = (
                self.main_roi[0] + cfg['bottom_right'][0],
                self.main_roi[1] + cfg['bottom_right'][1]
            )
            
            self.monitors.append({
                'name': cfg['name'],
                'rel_roi': (cfg['top_left'], cfg['bottom_right']),
                'abs_roi': (abs_tl, abs_br),
                'template': self._load_template(cfg['template_path']),
                'threshold': cfg['threshold'],
                'last_state': True,      # 初始状态设为非空
                'current_state': True,
                'triggered': False       # 触发标记
            })
        
        # 点击坐标转换
        self.click_pos = (
            self.main_roi[0] + click_position[0],
            self.main_roi[1] + click_position[1]
        )
        
        # 初始化计时器
        self.check_interval = check_interval
        self.last_click_time = 0
        
        # 创建调试窗口
        self.window_name = "Smart Grill Monitor"
        cv2.namedWindow(self.window_name, cv2.WINDOW_NORMAL)
        self._resize_window()

    def _load_template(self, path):
        """加载并预处理模板图像"""
        template = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
        if template is None:
            raise FileNotFoundError(f"模板文件不存在: {path}")
        return cv2.GaussianBlur(template, (3,3), 0)

    def _resize_window(self):
        """调整窗口尺寸"""
        scaled_w = int(self.main_roi[2] * self.display_scale)
        scaled_h = int(self.main_roi[3] * self.display_scale)
        cv2.resizeWindow(self.window_name, scaled_w, scaled_h)

    def _capture_main_region(self):
        """捕获主监控区域"""
        x, y, w, h = self.main_roi
        screen = pyautogui.screenshot(region=(x, y, w, h))
        return cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2GRAY), \
               cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2BGR)

    def _match_template(self, screen, template, scales=[0.9, 1.0, 1.1]):
        """多尺度模板匹配"""
        best_val = -1
        best_scale = 1.0
        best_loc = None
        
        for scale in scales:
            resized = cv2.resize(template, None, fx=scale, fy=scale)
            if resized.shape[0] > screen.shape[0] or resized.shape[1] > screen.shape[1]:
                continue
                
            result = cv2.matchTemplate(screen, resized, cv2.TM_CCOEFF_NORMED)
            _, max_val, _, max_loc = cv2.minMaxLoc(result)
            
            if max_val > best_val:
                best_val = max_val
                best_loc = max_loc
                best_scale = scale
                
        return best_val, best_loc, best_scale

    def _update_monitor_states(self, main_gray):
        """更新所有区域状态"""
        trigger_required = False
        current_time = time.time()
        
        for monitor in self.monitors:
            # 提取子区域
            (rx1, ry1), (rx2, ry2) = monitor['rel_roi']
            sub_region = main_gray[ry1:ry2, rx1:rx2]
            
            # 模板匹配
            confidence, _, _ = self._match_template(sub_region, monitor['template'])
            
            # 更新状态
            monitor['last_state'] = monitor['current_state']
            monitor['current_state'] = confidence >= monitor['threshold']
            
            # 状态变化检测（非空 → 空）
            if not monitor['current_state'] and monitor['last_state']:
                if not monitor['triggered'] and (current_time - self.last_click_time) > self.cooldown:
                    print(f"[{monitor['name']}] 状态变化 → 需要补充食材")
                    trigger_required = True
                    monitor['triggered'] = True
        
        return trigger_required

    def _perform_safe_click(self):
        """执行安全点击"""
        print(f"执行点击 @ {time.strftime('%H:%M:%S')}")
        pyautogui.click(*self.click_pos)
        self.last_click_time = time.time()
        
        # 重置所有触发标记
        for monitor in self.monitors:
            monitor['triggered'] = False

    def _draw_status(self, display):
        """绘制状态信息"""
        scaled_display = cv2.resize(display, 
                                   (int(self.main_roi[2]*self.display_scale),
                                    int(self.main_roi[3]*self.display_scale)))
        
        # 绘制冷却时间
        cooldown_remain = max(0, self.cooldown - (time.time() - self.last_click_time))
        cv2.putText(scaled_display, f"冷却剩余: {cooldown_remain:.1f}s", 
                   (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7*self.display_scale, 
                   (0, 255, 255), int(2*self.display_scale))
        
        return scaled_display

    def run(self):
        """主监控循环"""
        try:
            while True:
                start_time = time.time()
                
                # 捕获主区域图像
                main_gray, main_display = self._capture_main_region()
                
                # 更新所有区域状态
                if self._update_monitor_states(main_gray):
                    self._perform_safe_click()
                
                # 绘制调试信息
                debug_display = self._draw_status(main_display)
                
                # 显示画面
                cv2.imshow(self.window_name, debug_display)
                
                # 控制循环频率
                elapsed = time.time() - start_time
                wait_ms = max(1, int((self.check_interval - elapsed) * 1000))
                if cv2.waitKey(wait_ms) == 27:  # ESC退出
                    break
                    
        finally:
            cv2.destroyAllWindows()

if __name__ == "__main__":
    config = {
        'regions_config': [
            {
                'name': '左侧烤架',
                'top_left': (400, 250),
                'bottom_right': (500, 330),
                'template_path': 'exam/game/templates/empty1.png',
                'threshold': 0.85
            },
            {
                'name': '右侧烤架',
                'top_left': (520, 256),
                'bottom_right': (614, 344),
                'template_path': 'exam/game/templates/empty2.png',
                'threshold': 0.85
            }
        ],
        'click_position': (590, 730),
        'check_interval': 0.8,
        'display_scale': 0.5,
        'cooldown': 5.0
    }
    
    monitor = SmartGrillMonitor(**config)
    monitor.run()